package pub.tbc.toolkit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pub.tbc.toolkit.exception.GlobalException;
import pub.tbc.toolkit.function.Supplier;

/**
 * 
 * 闭包工具，抽象一些操作，业务中只要使用lambda表达式传入动作即可
 * 
 * @author tbc
 * @version 1.0 {2016年6月17日 下午1:43:57}
 * @since jdk1.8
 */
public class ClosureUtil {
	private static Logger log = LoggerFactory.getLogger(ClosureUtil.class);

	private ClosureUtil() {
		throw new AssertionError("No " + getClass().getCanonicalName() + " instances for you!");
	}

	/**
	 * 自用场景：
	 * <li>执行某项操作，返回一个值 ，比如执行sql语句:
	 * 
	 * <pre>
	 * SqlClosure.apply(() -> sessionExecutor.query(sql));
	 * </pre>
	 * 
	 * 此处捕获并打印异常信息，然后抛回，实际业务当中则不用再执行此项操作，只需将异常继续向上抛，交给统一异常处理模块处理就可
	 * 
	 * @param supplier
	 * @return
	 * @author tbc
	 * @version 1.0 {2016年6月17日 下午1:54:24}
	 */
	public static <T> T apply(Supplier<T> supplier) throws GlobalException {
		T r = null;
		try {
			r = supplier.get();
		} catch (Exception e) {
			log.error("运行出现异常：class: {}, msg: {}", ClosureUtil.class.getCanonicalName(), e.getMessage());
			StackTraceElement[] stacks = e.getStackTrace();
			for (StackTraceElement it : stacks) {
				log.error("stack -> {}", it);
			}
			throw new GlobalException();
		}
		return r;
	}

	/**
	 * ，增加默认值
	 * 
	 * @param supplier
	 * @param t
	 * @return
	 * @throws Exception
	 * @author tbc
	 * @version 1.0 {2016年6月17日 下午2:20:50}
	 */
	public static <T> T apply(Supplier<T> supplier, T t) throws GlobalException {
		T r = apply(supplier);
		if (Objs.isEmpty(r)) {
			return t;
		}
		return r;
	}

}
